/*
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package output;

import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

import tools.StringTools;

/**
 * This class represents an output for IRC and contains information regarding how and what should be sent etc.
 * 
 * 
 */
public class IRCOutput implements Comparable<IRCOutput> {
   private final int source;
   private final String sender;
   private final int priority;
   private final String preferredHandler;
   private final long timeCreated;
   private final List<String> output;

   private String target = "";
   private OutputTypeEnum delivery = null;

   public IRCOutput(final int source, final String sender, final int priority) {
	  this.source = source;
	  this.priority = priority;
	  this.sender = sender;
	  preferredHandler = "";
	  output = new LinkedList<String>();
	  timeCreated = Calendar.getInstance().getTimeInMillis();
   }

   public IRCOutput(final int source, final String sender, final int priority, final String preferredHandler) {
	  this.source = source;
	  this.priority = priority;
	  this.sender = sender;
	  this.preferredHandler = preferredHandler;
	  output = new LinkedList<String>();
	  timeCreated = Calendar.getInstance().getTimeInMillis();
   }

   public IRCOutput(final int source, final String sender, final String target, final OutputTypeEnum delivery, final int priority) {
	  this.source = source;
	  this.priority = priority;
	  this.sender = sender;
	  this.target = target;
	  this.delivery = delivery;
	  preferredHandler = "";
	  output = new LinkedList<String>();
	  timeCreated = Calendar.getInstance().getTimeInMillis();
   }

   public IRCOutput(final int source, final String sender, final String target, final OutputTypeEnum delivery,
		 final int priority, final String preferredHandler) {
	  this.source = source;
	  this.priority = priority;
	  this.sender = sender;
	  this.target = target;
	  this.delivery = delivery;
	  this.preferredHandler = preferredHandler;
	  output = new LinkedList<String>();
	  timeCreated = Calendar.getInstance().getTimeInMillis();
   }

   public void addOutput(final List<String> add) {
	  output.addAll(add);
   }

   public void addOutput(final String add) {
	  output.add(add);
   }

   @Override
   public int compareTo(final IRCOutput o) {
	  return (int) (priority == o.priority ? o.timeCreated - timeCreated : o.priority - priority);
   }

   @Override
   public boolean equals(final Object o) {
	  if (o == null)
		 return false;
	  if (o == this)
		 return true;
	  if (!(o instanceof IRCOutput))
		 return false;
	  IRCOutput other = (IRCOutput) o;
	  return source == other.source && sender.equals(other.sender) && getAddress().equals(other.getAddress())
			&& priority == other.priority && sameOutputList(other.output) && preferredHandler.equals(other.preferredHandler);
   }

   public String getAddress() {
	  if (StringTools.isNullOrEmpty(target) || delivery == null)
		 return "";
	  return delivery.getOutputType(source) + " " + target + " :";
   }

   public OutputTypeEnum getDelivery() {
	  return delivery;
   }

   public List<String> getOutput() {
	  return output;
   }

   public String getPreferredHandler() {
	  return preferredHandler;
   }

   public int getPriority() {
	  return priority;
   }

   public String getSender() {
	  return sender;
   }

   public String getTarget() {
	  return target;
   }

   public Long getTimeCreated() {
	  return timeCreated;
   }

   @Override
   public int hashCode() {
	  assert false : "hashCode not designed";
	  return 42;
   }

   private boolean sameOutputList(final List<String> list) {
	  if (output.size() != list.size())
		 return false;
	  for (int i = 0; i < output.size(); ++i) {
		 if (!output.get(i).equals(list.get(i)))
			return false;
	  }
	  return true;
   }

   public void setDelivery(final OutputTypeEnum delivery) {
	  this.delivery = delivery;
   }

   public void setTarget(final String target) {
	  this.target = target;
   }
}
